﻿using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using SwParaPlatform2.dlgRuleConfig;
using SwParaPlatform2.dlgUIConfig;
using SwParaPlatform2.logger;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SwParaPlatform2
{
    class Datafilter
    {
    }

    public interface ISwParaInterface
    {
        void ReloadAllData();
        string LoadAllData(string sFilePath=null);
        bool IsEndingWithMinusOne(string input);
        bool IsNotEndingWithMinusNum(string input);
        bool IsInRange(string numStr, string maxStr, string minStr);
        string ExecArgsList(List<Dictionary<string, object>> lFormulaList);
        Dictionary<string, Dictionary<string, object>> ConvertToNestedDictionary(Dictionary<string, object> sourceDict);
        Dictionary<string, object> GetNestedDictionary(Dictionary<string, object> rootDictionary, List<string> keys);
        Dictionary<string, Dictionary<string, string>> GetEquationsFromModelDoc2(IModelDoc2 modelDoc);
        IModelDoc2 GetTargetModelDoc2(List<string> componentHierarchy, IModelDoc2 activeDoc);
        IComponent2 GetTargetComponent(List<string> componentHierarchy, IModelDoc2 activeDoc);
        List<string> GetEquationNames(string sCompName);
        void PrintDictionary(Dictionary<string, object> objectDict, int indent);
        Dictionary<string, object> DeepCopyDictionary(Dictionary<string, object> original);
        Dictionary<string, object> ReverseDictionary(Dictionary<string, object> original);

    }

    public class SwParaInterface : ISwParaInterface
    {
        

        public SwParaInterface()
        {
        }

        public void ReloadAllData()
        {
            UIConfigModel.Instance.SetUIConfigData(DataStore.Instance.UIConfigData);
            RuleConfigModel.Instance.SetRuleonfigData(DataStore.Instance.RuleConfigData);
            RuleConfigModel.Instance.SetSelectDrwList(DataStore.Instance.DrwList);
        }

        public string LoadAllData(string sFilePath=null)
        {

            string UIElementName = "UIConfig";
            string RuleElementName = "RuleConfig";
            string PathElementName = "Path";
            string DrwElementName = "drwConfig";

            string Note_NameElementName = Defines.Note_NameElementName;
            string Name_NoteElementName = Defines.Name_NoteElementName;

            var loadDictionary = XmlHandler.LoadAllDictionaryFromXml(sFilePath);

            try
            {
                if(loadDictionary != null)
                {
                    DataStore.Instance.UIConfigData = (Dictionary<string, Dictionary<string, object>>)loadDictionary[UIElementName];
                    DataStore.Instance.RuleConfigData = (Dictionary<string, Dictionary<string, object>>)loadDictionary[RuleElementName];

                    //备注名
                    DataStore.Instance.dNote_NameData = (Dictionary<string, object>)loadDictionary[Note_NameElementName];
                    DataStore.Instance.dName_NoteData = (Dictionary<string, object>)loadDictionary[Name_NoteElementName];

                    Dictionary<string, Dictionary<string, object>> dFilePath = (Dictionary<string, Dictionary<string, object>>)loadDictionary[PathElementName];
                    string DocPath = (string)dFilePath["FileName"]["FilePath"];
                    string sSelectPath = (string)loadDictionary["SelectPath"];
                    DataStore.Instance.sDocPath = DocPath;

                    UIConfigModel.Instance.SetUIConfigData(DataStore.Instance.UIConfigData);
                    RuleConfigModel.Instance.SetRuleonfigData(DataStore.Instance.RuleConfigData);

                    if (loadDictionary.ContainsKey(DrwElementName))
                    {
                        Dictionary<string, Dictionary<string, object>> dDrwDict = (Dictionary<string, Dictionary<string, object>>)loadDictionary[DrwElementName];
                        List<string> DrwList = new List<string>();
                        try
                        {
                            DrwList = (List<string>)dDrwDict["drw"]["drw"];
                        }catch(Exception ex)
                        {
                            Logger.Instance.Log($"解析工程图列表失败，异常{ex.Message}");
                        }
                        DataStore.Instance.DrwList = DrwList;
                    }
                    

                    return sSelectPath;
                }
                else
                {
                    Logger.Instance.Log(LogLevel.Warn, $"读取配置文件失败");
                    return "";
                }
                
            }
            catch(Exception e)
            {
                Logger.Instance.Log(LogLevel.Warn, $"配置文件加载失败，异常{e.Message}");
                Logger.Instance.Log(LogLevel.Warn, $"配置文件加载失败，异常{e.StackTrace}");
                return "";
            }

        }

        public bool IsEndingWithMinusOne(string input)
        {
            if (string.IsNullOrEmpty(input))
                return false;

            // 检查字符串是否以“-1”结尾
            return input.EndsWith("-1");
        }

        public bool IsNotEndingWithMinusNum(string input)
        {
            if (string.IsNullOrEmpty(input))
                return true;

            // 使用正则表达式检查字符串是否不以“-num”结尾
            string pattern = @"-\d+$";
            return !Regex.IsMatch(input, pattern);
        }

        public string ExecArgsList(List<Dictionary<string, object>> lFormulaList)
        {
            string sFormula = "";
            foreach (var dFormula in lFormulaList)
            {
                string sType = (string)dFormula["Type"];
                string sValue = (string)dFormula["Value"];
                if (Defines.Type_List_Quot.Contains(sType))
                {
                    sFormula += $"'{sValue}'";
                }
                else
                {
                    sFormula += sValue;
                }
            }
            return sFormula;
        }

        public Dictionary<string, Dictionary<string, object>> ConvertToNestedDictionary(Dictionary<string, object> sourceDict)
        {
            var nestedDict = new Dictionary<string, Dictionary<string, object>>();

            foreach (var kvp in sourceDict)
            {
                if (kvp.Value is Dictionary<string, object> dictValue)
                {
                    nestedDict[kvp.Key] = dictValue;
                }
                else
                {
                    nestedDict[kvp.Key] = new Dictionary<string, object>
            {
                { "Value", kvp.Value }
            };
                }
            }

            return nestedDict;
        }

        /*
        传入一个列表[A,B,C,D,E,F]，想获取键F对应的字典

        currentDictionary = rootDictionary;：开始时，currentDictionary 指向根字典。
        foreach (string key in keys)：遍历列表中的每个键。 
        if (currentDictionary.ContainsKey("SubComp"))：检查当前字典是否包含 "SubComp" 键，并确认其值是 Dictionary<string, object> 类型。
        currentDictionary = subDictionary[key] as Dictionary<string, object>;：将 currentDictionary 更新为对应的子字典。

        如果在遍历过程中找不到某个键或结构不符合预期，抛出异常。
        */
        public Dictionary<string, object> GetNestedDictionary(Dictionary<string, object> rootDictionary, List<string> keys)
        {
            Dictionary<string, object> currentDictionary = rootDictionary;

            foreach (string key in keys)
            {
                if (currentDictionary.ContainsKey("SubComp") && currentDictionary["SubComp"] is Dictionary<string, object> subDictionary)
                {
                    if (subDictionary.ContainsKey(key))
                    {
                        currentDictionary = subDictionary[key] as Dictionary<string, object>;
                    }
                    else
                    {
                        Logger.Instance.Log($"属性 '{key}' 并未记录到配置中，请尝试保存后重新打开模型.");
                    }
                }
                else
                {
                    throw new Exception($"'SubComp' key not found or invalid structure encountered at key '{key}'.");
                }
            }

            return currentDictionary;
        }

        public bool IsInRange(string numStr, string maxStr, string minStr)
        {
            // 尝试将字符串转换为数字
            bool isNumValid = double.TryParse(numStr, out double num);
            bool isMaxValid = double.TryParse(maxStr, out double max);
            bool isMinValid = double.TryParse(minStr, out double min);

            // 检查所有的转换是否成功
            if (isNumValid && isMaxValid && isMinValid)
            {
                // 判断是否 MIN <= NUM <= MAX
                return min <= num && num <= max;
            }
            else
            {
                // 如果任意一个转换失败，说明不受限
                return true;
            }
        }

        public IModelDoc2 GetTargetModelDoc2(List<string> componentHierarchy, IModelDoc2 activeDoc)
        {
            if (componentHierarchy == null || componentHierarchy.Count == 0)
            {
                throw new ArgumentException("索引列表不能为NULL或者空列表");
            }

            if (activeDoc == null)
            {
                throw new Exception("当前没有激活文档");
            }

            // 验证列表中的第一个元素是否与当前文档匹配
            if (!activeDoc.GetPathName().EndsWith(componentHierarchy[0]))
            {
                throw new Exception("列表中的第一个元素与当前文档不匹配");
            }

            // 如果列表只有一个元素，直接返回当前文档
            if (componentHierarchy.Count == 1)
            {
                return activeDoc as IModelDoc2;
            }

            // 否则，按原逻辑逐级查找
            IModelDoc2 modelDoc = activeDoc;
            IAssemblyDoc assemblyDoc = activeDoc as IAssemblyDoc;
            IComponent2 currentComponent = null;

            for (int i = 1; i < componentHierarchy.Count; i++)
            {
                string componentName = componentHierarchy[i];

                if (assemblyDoc != null)
                {
                    currentComponent = _FindImmediateComponentByName(assemblyDoc, componentName);
                    
                    if (currentComponent == null)
                    {
                        break;
                        //throw new Exception($"Component {componentName} not found in assembly.");
                    }

                    int SuppState = currentComponent.GetSuppression2();
                    if (SuppState != (int)swComponentSuppressionState_e.swComponentFullyResolved)
                        currentComponent.SetSuppression2((int)swComponentSuppressionState_e.swComponentFullyResolved);

                    modelDoc = currentComponent.GetModelDoc2();
                    assemblyDoc = modelDoc as IAssemblyDoc;
                    currentComponent.SetSuppression2(SuppState);
                }
            }
            return modelDoc;
        }

        public IComponent2 GetTargetComponent(List<string> componentHierarchy, IModelDoc2 activeDoc)
        {
            if (componentHierarchy == null || componentHierarchy.Count == 0)
            {
                throw new ArgumentException("索引列表不能为NULL或者空列表.");
            }

            if (activeDoc == null)
            {
                throw new Exception("当前没有激活文档.");
            }

            // 验证列表中的第一个元素是否与当前文档匹配
            if (!activeDoc.GetPathName().EndsWith(componentHierarchy[0]))
            {
                throw new Exception("列表中的第一个元素与当前文档不匹配");
            }

            // 如果列表只有一个元素，那就只是顶层文档，不能索引
            if (componentHierarchy.Count == 1)
            {
                Logger.Instance.Log("传入的索引列表只包含顶层文件，无法索引零部件.");
                return null;
            }

            // 否则，按原逻辑逐级查找
            IModelDoc2 modelDoc = activeDoc;
            IAssemblyDoc assemblyDoc = activeDoc as IAssemblyDoc;
            IComponent2 tempComponent = null;
            IComponent2 currentComponent = null;

            for (int i = 1; i < componentHierarchy.Count; i++)
            {
                string componentName = componentHierarchy[i];

                if (assemblyDoc != null)
                {
                    tempComponent = _FindImmediateComponentByName(assemblyDoc, componentName);

                    if (tempComponent == null)
                    {
                        break;
                        //throw new Exception($"Component {componentName} not found in assembly.");
                    }

                    int SuppState = tempComponent.GetSuppression2();
                    if (SuppState != (int)swComponentSuppressionState_e.swComponentFullyResolved)
                        tempComponent.SetSuppression2((int)swComponentSuppressionState_e.swComponentFullyResolved);

                    currentComponent = tempComponent;
                    modelDoc = currentComponent.GetModelDoc2();
                    assemblyDoc = modelDoc as IAssemblyDoc;
                    tempComponent.SetSuppression2(SuppState);
                }
            }
            return currentComponent;
        }

        public Dictionary<string, Dictionary<string, string>> GetEquationsFromModelDoc2(IModelDoc2 modelDoc)
        {
            if (modelDoc == null)
            {
                throw new ArgumentException("ModelDoc2 object cannot be null.");
            }

            return _GetEquationsDictionary(modelDoc);
        }

        private IComponent2 _FindImmediateComponentByName(IAssemblyDoc assemblyDoc, string fileName)
        {
            // 获取所有子组件
            object[] components = (object[])assemblyDoc.GetComponents(false);

            // 遍历每个子组件
            foreach (var comp in components)
            {
                IComponent2 component = comp as IComponent2;

                if (component != null)
                {
                    // 获取组件的路径名
                    string componentPath = component.GetPathName();

                    // 提取路径中的文件名
                    string componentFileName = System.IO.Path.GetFileName(componentPath);

                    // 比较文件名
                    if (string.Equals(componentFileName, fileName, StringComparison.OrdinalIgnoreCase))
                    {
                        return component;
                    }
                }
            }

            // 如果找不到匹配的组件，返回 null
            return null;
        }

        private Dictionary<string, Dictionary<string, string>> _GetEquationsDictionary(IModelDoc2 model)
        {
            Dictionary<string, Dictionary<string, string>> equationsDict = new Dictionary<string, Dictionary<string, string>>();

            EquationMgr equationMgr = model.GetEquationMgr();

            int equationCount = equationMgr.GetCount();
            for (int i = 0; i < equationCount; i++)
            {
                string equationName = equationMgr.Equation[i];
                bool globalVarName = equationMgr.GlobalVariable[i];  // 获取方程式的名称
                string[] equationParts = equationName.Split('=');

                if (equationParts.Length == 2)
                {
                    string name = equationParts[0].Trim().Replace("\"", "");
                    string expression = equationParts[1].Trim().Replace("\"", "");
                    equationsDict[name] = new Dictionary<string, string> 
                    {
                        {"Value",  expression},
                        {"Global",  globalVarName.ToString()},
                    };
                }
            }

            return equationsDict;
        }

        public List<string> GetEquationNames(string sCompName)
        {
            List<string> EquationNames = new List<string>();

            if (DataStore.Instance.EquationData.TryGetValue(sCompName, out var equationData))
            {
                foreach (var Kvp in equationData)
                {
                    EquationNames.Add(Kvp.Key);
                }
            }

            return EquationNames;
        }

        public void PrintDictionary(Dictionary<string, object> objectDict, int indent)
        {
            foreach (var kvp in objectDict)
            {
                if (kvp.Value is string sValue)
                {
                    Logger.Instance.Log($"PrintDictionary - {new string(' ', indent)}{kvp.Key}: {sValue}");
                }
                else
                {
                    Logger.Instance.Log($"PrintDictionary - {new string(' ', indent)}{kvp.Key}:");
                }


                if (kvp.Value is Dictionary<string, object> nestedDict)
                {
                    PrintDictionary(nestedDict, indent + 2);
                }
                else if (kvp.Value is Dictionary<string, Dictionary<string, string>> nestedStringDict)
                {
                    PrintStringDictionary(nestedStringDict, indent + 2);
                }
                else if (kvp.Value is Dictionary<string, string> properties)
                {
                    PrintProperties(properties, indent + 2);
                }
            }
        }

        private void PrintStringDictionary(Dictionary<string, Dictionary<string, string>> dict, int indent)
        {
            foreach (var kvp in dict)
            {
                Logger.Instance.Log($"PrintStringDictionary - {new string(' ', indent)}{kvp.Key}:");
                PrintProperties(kvp.Value, indent + 2);
            }
        }

        private void PrintProperties(Dictionary<string, string> properties, int indent)
        {
            foreach (var prop in properties)
            {
                Logger.Instance.Log($"PrintProperties - {new string(' ', indent)}{prop.Key}: {prop.Value}");
            }
        }

        public Dictionary<string, object> DeepCopyDictionary(Dictionary<string, object> original)
        {
            var copy = new Dictionary<string, object>();

            foreach (var kvp in original)
            {
                if (kvp.Value is IDictionary dictionary)
                {
                    // 递归拷贝嵌套的字典
                    copy[kvp.Key] = DeepCopyDictionary(new Dictionary<string, object>((IDictionary<string, object>)dictionary));
                }
                else if (kvp.Value is IList list)
                {
                    // 拷贝列表
                    copy[kvp.Key] = DeepCopyList(list);
                }
                else
                {
                    // 直接拷贝值
                    copy[kvp.Key] = kvp.Value;
                }
            }

            return copy;
        }

        public IList DeepCopyList(IList original)
        {
            var copy = (IList)Activator.CreateInstance(original.GetType());

            foreach (var item in original)
            {
                if (item is IDictionary dictionary)
                {
                    copy.Add(DeepCopyDictionary(new Dictionary<string, object>((IDictionary<string, object>)dictionary)));
                }
                else if (item is IList list)
                {
                    copy.Add(DeepCopyList(list));
                }
                else
                {
                    copy.Add(item);
                }
            }

            return copy;
        }

        public Dictionary<string, object> ReverseDictionary(Dictionary<string, object> original)
        {
            var reversed = new Dictionary<string, object>();

            foreach (var kvp in original)
            {
                // 如果值已经在新字典中存在，处理重复值（例如，可以抛出异常、忽略等）
                if (reversed.ContainsKey((string)kvp.Value))
                {
                    throw new InvalidOperationException($"重复的值: {kvp.Value}");
                }

                reversed[(string)kvp.Value] = kvp.Key;
            }

            return reversed;
        }
    }
}
